﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Biosek.Core;
using System.IO;

namespace PairSampler
{
	public class DestinoHelper
	{
		public static void SavePositiveAndNegativePlain(string filename, PlainSequenceSet positiveSamples, PlainSequenceSet negativeSamples)
		{
			int alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".Length;
			using (var writer = new StreamWriter(filename))
			{
				writer.WriteLine("{0} {1}", positiveSamples.Count + negativeSamples.Count, alpha);
				foreach (var psample in positiveSamples)
				{
					WriteSample(1, writer, psample);
				}
				foreach (var psample in negativeSamples)
				{
					WriteSample(0, writer, psample);
				}
				writer.Close();
			}
		}

		public static void ReadPositiveAndNegativePlain(string filename, PlainSequenceSet positiveSamples, PlainSequenceSet negativeSamples)
		{
			int phase = 0;
			int samples = 0;
			int alpha = 0;
			using (var reader = new StreamReader(filename))
			{
				while (!reader.EndOfStream)
				{
					var line = reader.ReadLine().Trim();
					if (line.Length == 0 || line[0] == '#')
					{
						continue;
					}
					var parts = line.Split(' ');
					if (phase == 0)
					{						
						samples = int.Parse(parts[0]);
						alpha = int.Parse(parts[1]);
						phase = 1;
					}
					else if (phase == 1)
					{						
						if (parts.Length < 2)
						{
							throw new InvalidOperationException("Formato de archivo de secuencias invalido, linea incompleta");
						}
						// determina si es muestra positiva
						bool isPositive = int.Parse(parts[0]) == 1;
						var sampleLenght = int.Parse(parts[1]);
						if (parts.Length != sampleLenght + 2)
						{
							throw new InvalidOperationException("Formato de archivo de secuencias invalido, dimensiones invalidas");
						}

						// Lee la nueva muestra, convierte cada simbolo
						var sample = parts.Skip(2).Select(x => (byte)int.Parse(x)).ToArray();
						if(sample.Any(x => x >= alpha))
						{
							throw new InvalidOperationException("Formato de archivo de secuencias invalido, longitud de alfabeto incorrecta");
						}
						
						// etiqueta la muestra
						if (isPositive) positiveSamples.Add(sample);
						else negativeSamples.Add(sample);
					}
				}
			}
		}

		private static void WriteSample(int type, StreamWriter writer, byte[] psample)
		{
			var head = new[] { type, psample.Length };
			var line = head.Concat(psample.Select(x => (int)x));
			var lineStr = line.Select(x => x.ToString());
			var fullLineStr = string.Join(" ", lineStr);
			writer.WriteLine(fullLineStr);
		}
	}
}
